#include "SerialInator.h"


SerialInator::SerialInator(){
	this->_posActual =0;
}


SerialInator::~SerialInator(){
	this->_posActual =0;
}


// Al colocar la posicion actual del buffer que se esta procesando en cero
// se puede utilizar las otras operaciones (serializar/des-serializar)
void SerialInator::reset(){
	this->_posActual =0;
}


// Devuelve un puntero a la posicion actual que se esta procesando del buffer señalado
char* SerialInator::getPtroActual(char* dataBuffer){
	return dataBuffer + this->_posActual;
}


void SerialInator::serializar(char* &arrBytes, char c){
	arrBytes[this->_posActual] = c;
	this->_posActual++;
}


void SerialInator::serializar(char* &arrBytes, int valor){
	// Crea un puntero a "bytes" que apunta al valor entero
	char* ptr = reinterpret_cast<char*>(&valor);

	// Asigna los bytes del entero en reversa
	arrBytes[this->_posActual++] = ptr[3];
	arrBytes[this->_posActual++] = ptr[2];
	arrBytes[this->_posActual++] = ptr[1];
	arrBytes[this->_posActual++] = ptr[0];

}


void SerialInator::serializar(char* &arrBytes, unsigned long valor){
	// Crea un puntero a "bytes" que apunta al valor entero
	char* ptr = reinterpret_cast<char*>(&valor);

	// Asigna los bytes del entero en reversa
	for (int i=sizeof(valor)-1; i>=0; i--){
		arrBytes[this->_posActual++] = ptr[i];
	}
	/*arrBytes[this->_posActual++] = ptr[3];
	arrBytes[this->_posActual++] = ptr[2];
	arrBytes[this->_posActual++] = ptr[1];
	arrBytes[this->_posActual++] = ptr[0];*/
}

// Para serializar una cadena primero guarda su tamaño en bytes
void SerialInator::serializar(char* &arrBytes, std::string cadena){

	// Serializa la longitud de la cadena
	serializar(arrBytes, static_cast<int>(cadena.size()));

	// Copia los caracteres al buffer
	char* ptrCadena = &arrBytes[this->_posActual];
	cadena.copy(ptrCadena, cadena.size());
	this->_posActual += cadena.size();
}

//---------------------------------------------------------

void SerialInator::desSerializar(char* arrBytes, char &c){
	c = arrBytes[this->_posActual++];
}


void SerialInator::desSerializar(char* arrBytes, int &valor){
	// Extrae los bytes que forman parte del entero en reversa
	char val[4] = {0};
	val[3] = arrBytes[this->_posActual++];
	val[2] = arrBytes[this->_posActual++];
	val[1] = arrBytes[this->_posActual++];
	val[0] = arrBytes[this->_posActual++];

	// Convierte los bytes en un numero entero
	int* ptr = reinterpret_cast<int*>(val);
	valor = *ptr;
}


void SerialInator::desSerializar(char* arrBytes, unsigned long &valor){
	// Extrae los bytes que forman parte del entero en reversa
	char val[sizeof(unsigned long)] = {0};
	for (int i= sizeof(unsigned long)-1; i>=0; i--){
		val[i] = arrBytes[this->_posActual++];
	}
	/*
	val[3] = arrBytes[this->_posActual++];
	val[2] = arrBytes[this->_posActual++];
	val[1] = arrBytes[this->_posActual++];
	val[0] = arrBytes[this->_posActual++];
	*/
	// Convierte los bytes en un numero entero
	long int* ptr = reinterpret_cast<long int*>(val);
	valor = *ptr;
}


void SerialInator::desSerializar(char* arrBytes, std::string &cadena){
	// Primero extrae la longitud de la cadena
	int tamCadena;
	desSerializar(arrBytes, tamCadena);

	// Extrae la cadena en si
	cadena.assign(&arrBytes[this->_posActual], tamCadena);
	this->_posActual += tamCadena;
}

